#include <cstdint>
#include <iostream>
#include <vector>

#include "../source/byte_array.h"
#include "../source/log.h"
#include "../source/util.h"

void test()
{
    #define XX(type, len, write_fun, read_fun, base_len)                \
    {                                                                   \
        std::vector<type> v;                                            \
        for(auto i = 0; i < len; ++i)                                   \
        {                                                               \
            v.emplace_back(rand());                                     \
        }                                                               \
        ByteArray::ptr ba = std::make_shared<ByteArray>(base_len);      \
        for(auto& t: v)                                                 \
        {                                                               \
            ba->write_fun(t);                                           \
        }                                                               \
        ba->setPosition(0);                                             \
        for(size_t i = 0; i < v.size(); ++i)                            \
        {                                                               \
            type n = ba->read_fun();                                    \
            ASSERT(n == v[i]);                                          \
        }                                                               \
        ASSERT(ba->getReadSize() == 0)                                  \
        log_info("{}\t{}\t{}\ttest ok", #type, #write_fun, #read_fun);  \
        log_info("{}", ba->getSize());                                  \
    }                                                                   \

XX(int8_t,  10, writeFint8, readFint8, 1);
XX(uint8_t, 10, writeFuint8, readFuint8, 1);
XX(int16_t,  10, writeFint16,  readFint16, 1);
XX(uint16_t, 10, writeFuint16, readFuint16, 1);
XX(int32_t,  10, writeFint32,  readFint32, 1);
XX(uint32_t, 10, writeFuint32, readFuint32, 1);
XX(int64_t,  10, writeFint64,  readFint64, 1);
XX(uint64_t, 10, writeFuint64, readFuint64, 1);

XX(int32_t,  10, writeInt32,  readInt32, 1);
XX(uint32_t, 10, writeUint32, readUint32, 1);
XX(int64_t,  10, writeInt64,  readInt64, 1);
XX(uint64_t, 10, writeUint64, readUint64, 1);

#undef XX
}

void testFile()
{
    #define XX(type, len, write_fun, read_fun, base_len)                 \
    {                                                                    \
        std::vector<type> v;                                             \
        for(auto i = 0; i < len; ++i)                                    \
        {                                                                \
            v.emplace_back(rand());                                      \
        }                                                                \
        ByteArray::ptr ba = std::make_shared<ByteArray>(base_len);       \
        for(auto& t: v)                                                  \
        {                                                                \
            ba->write_fun(t);                                            \
        }                                                                \
        ba->setPosition(0);                                              \
        for(size_t i = 0; i < v.size(); ++i)                             \
        {                                                                \
            type n = ba->read_fun();                                     \
            ASSERT(n == v[i]);                                           \
        }                                                                \
        ba->setPosition(0);                                              \
        ba->writeToFile("./" #type "_" #len "-" #read_fun ".dat");       \
        ByteArray::ptr readFile = std::make_shared<ByteArray>(base_len); \
        readFile->readFromFile("./" #type "_" #len "-" #read_fun ".dat");\
        readFile->setPosition(0);                                        \
        log_info("{}\t{}\t{}\ttest ok", #type, #write_fun, #read_fun);   \
        log_info("ba      :{}", ba->toHexString());                      \
        log_info("readFile:{}", readFile->toHexString());                \
    }                                                                    \

XX(int8_t,  10, writeFint8, readFint8, 1);      

#undef XX                                                      
}



int main(void)
{
    // test();
    testFile();
    log_debug("test ok");

    return 0;
}